/**
* Project: yui3-common-hub
 * Class HubXmlParser
 * Version 1.0
 * File Created at 2018年8月9日
 * $Id$
 * 
 * Copyright 2010-2015 Yui.com Corporation Limited.
 * All rights reserved.
 *
 * This software is the confidential and proprietary information of
 * Yui Personal. ("Confidential Information").  You shall not
 * disclose such Confidential Information and shall use it only in
 * accordance with the terms of the license agreement you entered into
 * with Yui.com.
 */
package yui.comn.hub.xml.parser;

import java.io.InputStream;
import java.io.Serializable;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.ClassUtils;
import org.apache.commons.lang3.StringUtils;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.baomidou.mybatisplus.annotation.TableName;

import yui.comn.hub.annotation.Note;
import yui.comn.hub.annotation.TableNote;
import yui.comn.hub.data.handler.impl.EnumClassHubDataHandler;
import yui.comn.hub.model.Clazz;
import yui.comn.hub.model.HubConstant;
import yui.comn.hub.model.HubXmlColumn;
import yui.comn.hub.model.HubXmlColumnAttr;
import yui.comn.hub.model.HubXmlElement;
import yui.comn.hub.model.HubXmlHandlerConfig;
import yui.comn.hub.model.Symbol;
import yui.comn.hub.utils.HubStringUtils;
import yui.comn.hub.utils.StrUtils;
import yui.comn.hub.xml.plugins.HubXmlPlugin;


/**
 * 数据装换中转站-xml解析
 * @author yuyi (1060771195@qq.com)
 */
@SuppressWarnings("unchecked")
public class HubXmlParser implements Serializable{
    private static final long serialVersionUID = -8495177897485601103L;

    private Logger log = LoggerFactory.getLogger(HubXmlParser.class);
    
    private HubXmlPlugin hubXmlPlugin;
    
    public HubXmlParser(HubXmlPlugin hubXmlPlugin) {
        this.hubXmlPlugin = hubXmlPlugin;
    }

    /**
     * 获取Map,主要用于输出字段描述
     * 例如  {
     *       "usNm": "登陆名",
     *       "nkNm": "昵称",
     *       "roleList": {
     *           "nm": "名称",
     *           "rmks": "备注"
     *        }
     *      }
     */
    public Map<String, Object> parseXmlGridColToKvMap(Class<?> clazz, String name) {
        List<HubXmlColumn> colList = parseXmlColToList(clazz, HubXmlElement.grid.name(), name);
        return getGridKvMap(colList);
    }
    
    /**
     * 迭代获取Map,主要用于输出字段描述
     */
    private Map<String, Object> getGridKvMap(List<HubXmlColumn> colList) {
        Map<String, Object> map = new LinkedHashMap<>();
        
        for (HubXmlColumn column : colList) {
            if (null == column.getCollections()) {
                putMapData(map, column.getGroup(), column.getName(), column.getDescr());

                if (StringUtils.isNotBlank(column.getToName())) {
                    putMapData(map, column.getGroup(), column.getToName(), column.getDescr());
                }
            } else {
                Map<String, List<HubXmlColumn>> collections = column.getCollections();
                for (Entry<String, List<HubXmlColumn>> entry : collections.entrySet()) {
                    map.put(column.getName(), getGridKvMap(entry.getValue()));
                }
            }
        }
        
        return map;
    }

    private void putMapData(Map<String, Object> map, String group, String name, String desc) {
        if (StringUtils.isBlank(group)) {
            map.put(name, desc);
        } else {
            Map<String, Object> groupMap = (Map<String, Object>) map.get(group);
            if (null == groupMap) {
                groupMap = new LinkedHashMap<>();
                map.put(group, groupMap);
            }
            groupMap.put(name, desc);
        }
    }
    
    /**
     * 解析xml,获取grid类型list,用于字段过滤
     */
    public Map<String, String> parseXmlGridColToFieldKvMap(Class<?> clazz, String name) {
        List<HubXmlColumn> colList = parseXmlColToList(clazz, HubXmlElement.grid.name(), name);
        Map<String, String> map = new LinkedHashMap<>();
        for (HubXmlColumn hubXmlColumn : colList) {
            if (null != hubXmlColumn.getCollections()) {
                continue;
            }
            
            String column = hubXmlColumn.getColumn();
            if (StringUtils.isNotBlank(column)) {
            	map.put(hubXmlColumn.getName(), column);
            } else {
            	String mapper = hubXmlColumn.getMapper();
            	if (StringUtils.isBlank(mapper)) {
            		continue;
            	}
            	
            	if (StringUtils.contains(mapper, Symbol.DOT)) {
            		String tableAndField = HubStringUtils.getTableAndField(mapper);
            		map.put(hubXmlColumn.getName(), tableAndField);
            	}
            }
            
        }
        return map;
    }
    
    /**
     * 解析xml,获取grid类型list
     */
    public List<HubXmlColumn> parseXmlGridColToList(Class<?> clazz, String name) {
        return parseXmlColToList(clazz, HubXmlElement.grid.name(), name);
    }
    
    /**
     * 解析xml,获取search类型list
     */
    public List<HubXmlColumn> parseXmlSearchColToList(Class<?> clazz, String name) {
        return parseXmlColToList(clazz, HubXmlElement.search.name(), name);
    }
    
    /**
     * 解析xml,获取search类型map
     */
    public Map<String, String> parseXmlSearchColToMap(Class<?> clazz, String name) {
        List<HubXmlColumn> columns = parseXmlColToList(clazz, HubXmlElement.search.name(), name);
        
        Map<String, String> map = new HashMap<String, String>();
        for (HubXmlColumn column : columns) {
            map.put(column.getName(), column.getMapper());
        }
        
        return map;
    }
    
    /**
     * 解析xml,获取对应的type类型的元素列表
     */
    public List<HubXmlColumn> parseXmlColToList(Class<?> clazz, String type, String name) {
        Element pel = parseXmlToElement(clazz, type, name);
        
        String handler = pel.attributeValue(HubXmlColumnAttr.handler.name());
        String mapperNm = pel.attributeValue(HubXmlColumnAttr.mapper.name());

        // mapperNm = StringUtils.isNotBlank(mapperNm) ? mapperNm : HubConstant.MAPPING_DEFAULT_NAME;

        Element mel = null;
        if (StringUtils.isNotBlank(mapperNm)) {
            mel = parseXmlToElement(clazz, HubXmlElement.mapping.name(), mapperNm);
        }
        Map<String, List<HubXmlHandlerConfig>> keyHandlerMap = getKeyHandlerMap(mel);

        List<Element> elements = pel.elements();
        
        List<HubXmlColumn> columns = parseXmlColToList(clazz, elements, type, handler, keyHandlerMap);
        //排序
        Collections.sort(columns);
        return columns;
    }

    /**
     * 比如testAVo.type 对应的handler
     * @param mel 映射配置
     * @return
     */
    private Map<String, List<HubXmlHandlerConfig>> getKeyHandlerMap(Element mel) {
        if (null == mel) {
            return null;
        }
        Map<String, List<HubXmlHandlerConfig>> map = new HashMap<>();
        List<Element> elements = mel.elements();
        for (Element el : elements) {
            String name = el.attributeValue(HubXmlColumnAttr.name.name());
            String mapper = el.attributeValue(HubXmlColumnAttr.mapper.name());

            List<HubXmlColumn> columns = new ArrayList<>();
            addGridColumnByType(columns, null, null, mapper, null, null);

            columns.forEach(col -> {
                if (null != col.getHandlerConfigs() && !col.getHandlerConfigs().isEmpty()) {
                    map.put(name + Symbol.DOT + col.getName(), col.getHandlerConfigs());
                }
            });

        }
        return map;
    }
    
    
    /**
     * 解析xml,获取对应的type类型的元素列表
     */
    public List<HubXmlColumn> parseXmlColToList(Class<?> clazz, List<Element> elements,
                                                String type, String pHandler, Map<String, List<HubXmlHandlerConfig>> keyHandlerMap) {
        List<HubXmlColumn> columns = new ArrayList<>();
        
        for (Element el : elements) {
            String prefix = el.attributeValue(HubXmlColumnAttr.prefix.name());
            String group = el.attributeValue(HubXmlColumnAttr.group.name());
            String className = el.attributeValue(HubXmlColumnAttr.type.name());
            if (StringUtils.isBlank(className)) {
                // 继承
                if (StringUtils.equals(HubXmlElement.grid.name(), el.getQualifiedName())
                        || StringUtils.equals(HubXmlElement.search.name(), el.getQualifiedName())) {
                    columns.addAll(parseXmlColToList(clazz, type, el.attributeValue(HubXmlColumnAttr.name.name())));
                    continue;
                }
                
                HubXmlColumn col = new HubXmlColumn();
                
                String colName = el.attributeValue(HubXmlColumnAttr.name.name());
                String colToName = el.attributeValue(HubXmlColumnAttr.toName.name());
                
                if (StringUtils.equals(HubXmlElement.collection.name(), el.getQualifiedName())) {
                    List<HubXmlColumn> subColumns = parseXmlColToList(clazz, el.elements(), type, pHandler, keyHandlerMap);
                    col.putCollection(colName, subColumns);
                }
                
                //如果前缀不为空
                if (StringUtils.isNotBlank(prefix)) {
                    colName = StrUtils.upperCaseFirstCharAndAddPrefix(colName, prefix);
                    if (StringUtils.isNotBlank(colToName)) {
                        colToName = StrUtils.upperCaseFirstCharAndAddPrefix(colToName, prefix);
                    }
                }
                
                col.setName(colName);
                col.setMapper(el.attributeValue(HubXmlColumnAttr.mapper.name()));
                col.setColumn(el.attributeValue(HubXmlColumnAttr.column.name()));
                col.setDescr(el.attributeValue(HubXmlColumnAttr.descr.name()));
                col.setGroup(group);
                
                String viewOrder = el.attributeValue(HubXmlColumnAttr.viewOrder.name());
                if (StringUtils.isNotBlank(viewOrder)) {
                    col.setViewOrder(Integer.valueOf(viewOrder));
                }
                
                StringBuffer handler = new StringBuffer();
                if (StringUtils.isNotBlank(pHandler)) {
                	handler.append(pHandler);
                	if (!StringUtils.endsWith(pHandler, Symbol.SEMICOLON)) {
                		handler.append(Symbol.SEMICOLON);
                	}
                }
                String newHandler = el.attributeValue(HubXmlColumnAttr.handler.name());
                if (StringUtils.isNotBlank(newHandler)) {
                	handler.append(newHandler);
                }
                
                col.setHandler(handler.toString());
                col.setToName(colToName);
                col.setToDescr(el.attributeValue(HubXmlColumnAttr.toDescr.name()));
                col.setEnCls(el.attributeValue(HubXmlColumnAttr.enCls.name()));
                
                List<HubXmlHandlerConfig> handlerConfigs = getConfigs(col.getHandler(), colName, group);

                if (null != keyHandlerMap) {
                    List<HubXmlHandlerConfig> handlerConfigs1 = keyHandlerMap.get(col.getMapper());
                    if (null != handlerConfigs1) {
                        handlerConfigs.addAll(handlerConfigs1);
                        for (HubXmlHandlerConfig hc : handlerConfigs) {
                            hc.setGroup(group);
                            if (null != hc.getColumn()) {
                                hc.getColumn().setGroup(group);
                                columns.add(hc.getColumn());
                            }
                        }
                    }
                }

                col.setHandlerConfigs(enumClassColumnHandle(columns, handlerConfigs, col));

                columns.add(col);
            } else {
                //通过对象类有Note属性的字段，解析成List<HubColumn>
                if (StringUtils.equals(HubXmlElement.grid.name(), type)){
                    String classObj = el.attributeValue(HubXmlColumnAttr.typeObj.name());
                    addGridColumnByType(columns, group, prefix, className, classObj, pHandler);
                } else {
                    addSearchColumnByType(columns, group, prefix, className);
                }
            }
        }
        //排序
        Collections.sort(columns);
        return columns;
    }
    
    /**
     * 把class中有Note属性的字段，加入Grid列表中
     */
    private void addGridColumnByType(List<HubXmlColumn> columns, String group, String prefix, String className, String classObj, String pHandler) {
        try {
            // Class<?> voClazz = Class.forName(className);
            Class<?> clazz = Class.forName(className);
            String tableName = getTableName(clazz);
            String classSimpleName = StrUtils.lowerCaseFirstChar(clazz.getSimpleName());
            
            for (; clazz != Object.class; clazz = clazz.getSuperclass()) {
                Field[] fields = clazz.getDeclaredFields();
                for (Field field : fields) {
                    Note note = field.getAnnotation(Note.class);
                    if (null != note) {
                        HubXmlColumn col = new HubXmlColumn();
                        
                        String name = field.getName();
                        String toName = note.toName();
                        
                        //如果前缀不为空
                        if (StringUtils.isNotBlank(prefix)) {
                            name = StrUtils.upperCaseFirstCharAndAddPrefix(name, prefix);
                            if (StringUtils.isNotBlank(toName)) {
                                toName = StrUtils.upperCaseFirstCharAndAddPrefix(toName, prefix);
                            }
                        }
                        
                        //获取字段描述
                        String descr = note.value();
                        if (StringUtils.isBlank(descr)) {
                            descr = note.descr();
                        }
                        
                        col.setName(name);
                        //比如sysUserVo.usNm
                        if (StringUtils.isNotEmpty(classObj)) {
                            col.setMapper(classObj + Symbol.DOT + field.getName());
                        } else {
                            col.setMapper(classSimpleName + Symbol.DOT + field.getName());
                        }
                        
                        String attrName = StrUtils.toUnderlineAndLowerCaseByHump(field.getName());
                        col.setColumn(tableName + Symbol.DOT + attrName);
                        
                        StringBuffer handler = new StringBuffer();
                        if (StringUtils.isNotBlank(pHandler)) {
                        	handler.append(pHandler);
                        	if (!StringUtils.endsWith(pHandler, Symbol.SEMICOLON)) {
                        		handler.append(Symbol.SEMICOLON);
                        	}
                        }
                        String newHandler = note.handler();
                        if (StringUtils.isNotBlank(newHandler)) {
                        	handler.append(newHandler);
                        }
                        
                        col.setHandler(handler.toString());
                        // col.setHandler(note.handler());
                        col.setTypeObj(classObj);
                        col.setDescr(descr);
                        col.setViewOrder(note.viewOrder());
                        col.setToName(toName);
                        col.setToDescr(note.toDescr());
                        col.setEnCls(note.enCls().getName());
                        col.setGroup(group);
                        
                        // annotationHandle(field, col);
                        hubXmlPlugin.xmlHandle(field.getAnnotations(), col);
                        
                        List<HubXmlHandlerConfig> handlerConfigs = getConfigs(col.getHandler(), name, group);
                        col.setHandlerConfigs(enumClassColumnHandle(columns, handlerConfigs, col));
                        
                        if (null != col) {
                            columns.add(col);
                        }
                    }
                }
            }
        } catch (Exception e) {
            String errMsg = "通过className解析Column失败， className:" + className;
            log.error(errMsg, e);
            throw new RuntimeException(errMsg, e);
        }
    }
    
//    @SuppressWarnings("rawtypes")
//    private void annotationHandle(Field field, HubXmlColumn col) {
//        Annotation[] annos = field.getAnnotations();
//        for (Annotation anno : annos) {
//            if (anno.annotationType().isAssignableFrom(JsonSerialize.class)) {
//                Class<? extends JsonSerializer> using = ((JsonSerialize) anno).using();
//                if (using.isAssignableFrom(ToStringSerializer.class)) {
//                    col.addHandler(ToStringHubDataHandler.REG_NAME);
//                }
//            } else if (anno.annotationType().isAssignableFrom(JsonIgnore.class)) {
//                if (null != anno) {
//                    col = null;
//                }
//            } else if (anno.annotationType().isAssignableFrom(JsonFormat.class)) {
//                String pattern = ((JsonFormat) anno).pattern();
//                col.addHandler("jsonFormat(" + pattern + ")");
//            }
//        }
//        /*JsonSerialize anno = field.getAnnotation(JsonSerialize.class);
//        if (null != anno) {
//            Class<? extends JsonSerializer> using = anno.using();
//            if (using.isAssignableFrom(ToStringSerializer.class)) {
//                col.addHandler(ToStringHubDataHandler.REG_NAME);
//            }
//        }
//        JsonIgnore jsonIgnore = field.getAnnotation(JsonIgnore.class);
//        if (null != jsonIgnore) {
//            col = null;
//        }*/
//    }
    
    /**
     * 把class中属性的值，加入search列表中
     */
    private void addSearchColumnByType(List<HubXmlColumn> columns, String group, String prefix, String className) {
        try {
            // Class<?> voClazz = Class.forName(className);
            Class<?> clazz = Class.forName(className);
            String tableName = getTableName(clazz);
            for (; clazz != Object.class; clazz = clazz.getSuperclass()) {
                Field[] fields = clazz.getDeclaredFields();
                for (Field field : fields) {
                    Note note = field.getAnnotation(Note.class);
                    if (null != note) {
                        HubXmlColumn col = new HubXmlColumn();
                        
                        String name = field.getName();
                        //如果前缀不为空
                        if (StringUtils.isNotBlank(prefix)) {
                            name = StrUtils.upperCaseFirstCharAndAddPrefix(name, prefix);
                        }
                        
                        col.setName(name);
                        
                        String attrName = StrUtils.toUnderlineAndLowerCaseByHump(field.getName());
                        col.setColumn(tableName + Symbol.DOT + attrName);
                        col.setMapper(tableName + Symbol.DOT + attrName);
                        
                        col.setDescr(note.value());
                        
                        col.setViewOrder(note.viewOrder());
                        col.setEnCls(note.enCls().getName());
                        col.setGroup(group);
                        
                        hubXmlPlugin.xmlHandle(field.getAnnotations(), col);
                        
                        List<HubXmlHandlerConfig> handlerConfigs = getConfigs(col.getHandler(), name, group);
                        col.setHandlerConfigs(enumClassColumnHandle(columns, handlerConfigs, col));
                        
                        columns.add(col);
                    }
                }
            }
        } catch (Exception e) {
            String errMsg = "通过className解析Column失败， className:" + className;
            log.error(errMsg, e);
            throw new RuntimeException(errMsg, e);
        }
    }
    
    private String getTableName(Class<?> clazz) {
        String tableName = null;
        
        // 先通过对象类TableName注释获取表名
        TableName tableNameAnno = clazz.getAnnotation(TableName.class);
        if (null != tableNameAnno) {
        	tableName = tableNameAnno.value();
        }
        
        if (StringUtils.isBlank(tableName)) {
        	//先通过对象类TableNote注释获取表名，如果没有该属性，通过解析对象类名获取表名，比如SysUserVo,得到T_SYS_USER
        	TableNote tableNote = clazz.getAnnotation(TableNote.class);
        	if (null != tableNote) {
        		//通过注解取表名
        		tableName = tableNote.value();
        		if (StringUtils.isBlank(tableName)) {
        			tableName = tableNote.tableName();
        		}
        	}
        }
        
        if (StringUtils.isBlank(tableName)) {
        	//通过解析对象类名获取表名
        	tableName = HubStringUtils.getTableNameByVoName(clazz.getSimpleName());
        }
        return tableName;
    }
    
    private List<HubXmlHandlerConfig> enumClassColumnHandle(List<HubXmlColumn> columns, List<HubXmlHandlerConfig> handlerConfigs, HubXmlColumn col) {
        if (StringUtils.isNotBlank(col.getEnCls())
                && !StringUtils.equals(col.getEnCls(), Clazz.class.getName())) {
            HubXmlHandlerConfig handlerConfig = getConfig(EnumClassHubDataHandler.REG_NAME, col.getName(), col.getGroup());
            // handlerConfig.getParams().add(col.getEnCls());
            try {
                List<Object> params = new ArrayList<>();
                
                Class<?> enumClass = null;
                if (!StringUtils.contains(col.getEnCls(), Symbol.PIPE)) {
                    enumClass = ClassUtils.getClass(col.getEnCls());
                    params.add(col.getEnCls());
                } else {
                    String[] ens = StringUtils.split(col.getEnCls(), Symbol.PIPE);
                    enumClass = ClassUtils.getClass(ens[0]);
                    params.add(ens[0]);
                    params.add(ens[1]);
                    if (ens.length == 3) {
                    	params.add(ens[2]);
                    }
                }
                handlerConfig.setParams(params);
                
                handlerConfig.setEnCls(enumClass);
                col.setEnumClass(enumClass);
                
//                if (null == handlerConfigs) {
//                    handlerConfigs = new ArrayList<>();
//                }
                handlerConfigs.add(handlerConfig);
                
                // 如果参数为个数少于2 或者 参数个数为2且值不为false
                if (params.size() < 2 || (params.size() > 1 && Boolean.valueOf(params.get(1).toString()))) {
                    HubXmlColumn col2 = new HubXmlColumn();
                    col2.setDescr(col.getDescr() + HubConstant.KEY_SUFFIX_DSR);
                    
                    String name = col.getName() + HubConstant.KEY_SUFFIX_CD;
                    //如果前缀不为空
                    if (StringUtils.isNotBlank(col.getPrefix())) {
                        name = StrUtils.upperCaseFirstCharAndAddPrefix(name, col.getPrefix());
                    }
                    col2.setName(name);
                    col2.setGroup(col.getGroup());
                    
                    columns.add(col2);

                    handlerConfig.setColumn(col2);
                }
            } catch (ClassNotFoundException e) {
                log.error(col.getEnCls() + "类不存在");
            }
        }
        return handlerConfigs;
    }
    
    /**
     * 解析column中的handler属性成为List<HubXmlHandlerConfig>
     */
    private List<HubXmlHandlerConfig> getConfigs(String handler, String name, String group) {
        if (StringUtils.isBlank(handler)) {
            return new ArrayList<>();
        }
        
        List<HubXmlHandlerConfig> handlerConfigs = new ArrayList<>();
        
        String[] configs = StringUtils.split(handler, Symbol.SEMICOLON);
        for (String config : configs) {
            // handlerConfigs.add(getConfig(config, name));
            addHandlerConfigs(handlerConfigs, getConfig(config, name, group));
        }
        
        return handlerConfigs;
    }
    
    private void addHandlerConfigs(List<HubXmlHandlerConfig> handlerConfigs,
                                   HubXmlHandlerConfig handlerConfig) {
        boolean duplicateFlag = false;
        for (HubXmlHandlerConfig hc : handlerConfigs) {
            if (StringUtils.equals(hc.getHandler(), handlerConfig.getHandler())) {
                duplicateFlag = true;
                break;
            }
        }
        if (!duplicateFlag) {
            handlerConfigs.add(handlerConfig);
        }
    }
    
    /**
     * 解析column中的handler属性成为HubXmlHandlerConfig
     */
    private HubXmlHandlerConfig getConfig(String config, String name, String group) {
        //如果没有括号
        int openParenIndex = StringUtils.indexOf(config, Symbol.OPNE_PAREN);
        int closeParenIndex = StringUtils.indexOf(config, Symbol.CLOSE_PAREN);
        if (openParenIndex == -1 || closeParenIndex == -1) {
            return new HubXmlHandlerConfig(group, name, config);
        }
        
        String handler = StringUtils.substringBefore(config, Symbol.OPNE_PAREN);
        //空括号
        if (closeParenIndex - openParenIndex == -1) {
            return new HubXmlHandlerConfig(name, handler);
        }
        
        String paramStr = StringUtils.substringBetween(config, Symbol.OPNE_PAREN, Symbol.CLOSE_PAREN);
        String[] tempParams = StringUtils.split(paramStr, Symbol.COMMA);
        
        List<Object> params = new ArrayList<>();
        // params.add(selfParam);
        for (String tempParam : tempParams) {
            params.add(tempParam);
        }
        
        HubXmlHandlerConfig handlerConfig = new HubXmlHandlerConfig(group, name, handler, params);
        
        if (StringUtils.equals(EnumClassHubDataHandler.REG_NAME, handler) && !params.isEmpty()) {
            Class<?> enumClass;
            try {
                enumClass = ClassUtils.getClass(params.get(0).toString());
                handlerConfig.setEnCls(enumClass);
            } catch (ClassNotFoundException e) {
                log.error("ClassNotFoundException " + params.get(0), e);
            }
        }
        
        return handlerConfig;
    }
    
    /**
     * 解析xml,获取对应的type类型元素
     */
    private Element parseXmlToElement(Class<?> clazz, String type, String name) {
        Document document = this.parseXmlToDoc(clazz, type, name);
        Element rootEl = document.getRootElement();
        
        List<Element> elements = rootEl.elements(type);
        
        for (Element el : elements) {
            if (StringUtils.equals(name, el.attributeValue(HubXmlColumnAttr.name.name()))) {
                return el;
            }
        }
        
        String errMsg = "class:" + clazz.getSimpleName() + "; type:" + type + "; name:" + name + ", 找不到对应的元素";
        log.error(errMsg);
        throw new RuntimeException(errMsg);
        
    }
    
    /**
     * 把xml文件解析成 Document类对象
     */
    private Document parseXmlToDoc (Class<?> clazz, String type, String name) {
        InputStream ins = clazz.getResourceAsStream(getXmlName(clazz));
        try {
            return new SAXReader().read(ins);
        } catch (DocumentException e) {
            String errMsg = "class:" + clazz.getSimpleName() + "; type:" + type + "; name:" + name;
            log.error(errMsg, e);
            throw new RuntimeException(errMsg, e);
        } finally {
            IOUtils.closeQuietly(ins);
        }
    }
    
    /**
     * 通过class获取对应的xml名称, 比如sysUserController.class类获取sysUserController.xml文件名
     */
    private String getXmlName(Class<?> clazz) {
        return new StringBuffer().append(clazz.getSimpleName()).append(".xml").toString();
    }
}
